/*
 * Copyright 2013 meichenhui
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.googlecode.zet.tool.pluginanalyzer;

import java.util.Collections;
import java.util.jar.Manifest;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.eclipse.osgi.service.resolver.BundleDescription;
import org.eclipse.osgi.service.resolver.BundleSpecification;
import org.eclipse.osgi.service.resolver.ExportPackageDescription;
import org.eclipse.osgi.service.resolver.GenericDescription;
import org.eclipse.osgi.service.resolver.GenericSpecification;
import org.eclipse.osgi.service.resolver.HostSpecification;
import org.eclipse.osgi.service.resolver.ImportPackageSpecification;
import org.eclipse.osgi.service.resolver.NativeCodeSpecification;
import org.eclipse.osgi.service.resolver.State;
import org.eclipse.osgi.service.resolver.VersionRange;
import org.eclipse.osgi.util.ManifestElement;
import org.osgi.framework.Constants;
import org.osgi.framework.Version;

/**
 * 插件配置描述<br/>
 * 没有完全实现{@link BundleDescription}接口,因为用不上那么多属性.<br/>
 * 调用没有实现的接口会抛出{@link UnsupportedOperationException}异常.
 * 
 * @author meichenhui
 *
 */
public class SimpleBundleDescription implements BundleDescription {
    
    private String name;
    
    private Version version;
    
    private String symbolicName;
    
    private BundleSpecification[] requireBundles;
    
    private String[] executionEnvironments;
    
    public SimpleBundleDescription(Manifest manifest){
        setName(manifest.getMainAttributes().getValue(Constants.BUNDLE_NAME));
        setSymbolicName(cleanSymbolicName(manifest.getMainAttributes().getValue(Constants.BUNDLE_SYMBOLICNAME)));
        setExecutionEnviroments(ManifestElement.getArrayFromList(manifest.getMainAttributes().getValue(Constants.BUNDLE_REQUIREDEXECUTIONENVIRONMENT)));
        setRequireBundles(createRequiredBundles(Util.selectRequireBundles(manifest)));
        setVersion(Version.parseVersion(manifest.getMainAttributes().getValue(Constants.BUNDLE_VERSION)));
    }
    
    protected String cleanSymbolicName(String completSymbolicName){
        if (StringUtils.containsNone(completSymbolicName, ";")){
            return completSymbolicName.trim();
        }
        return StringUtils.split(completSymbolicName, ";")[0].trim();
    }
    
    protected void setName(String name){
        this.name = name;
    }

    @Override
    public String getName() {
        return name;
    }
    
    protected void setVersion(Version version){
        this.version = version;
    }

    @Override
    public Version getVersion() {
        return version;
    }

    protected void setSymbolicName(String symbolicName){
        this.symbolicName = symbolicName;
    }

    @Override
    public String getSymbolicName() {
        return symbolicName;
    }
    
    protected void setRequireBundles(BundleSpecification[] requireBundles){
        this.requireBundles = requireBundles;
    }
    
    @Override
    public BundleSpecification[] getRequiredBundles() {
        return requireBundles;
    }
    
    protected void setExecutionEnviroments(String[] executionEnviroments){
        this.executionEnvironments = executionEnviroments;
    }

    @Override
    public String[] getExecutionEnvironments() {
        return executionEnvironments;
    }
    
    private static BundleSpecification[] createRequiredBundles(ManifestElement[] specs) {
        if (specs == null)
            return new RequireBundleDescription[0];
        BundleSpecification[] result = new BundleSpecification[specs.length];
        for (int i = 0; i < specs.length; i++)
            result[i] = new RequireBundleDescription(specs[i].getValue(),new VersionRange(specs[i].getAttribute(Constants.BUNDLE_VERSION_ATTRIBUTE)));
        return result;
    }
    
    @Override
    public int hashCode() {
        return HashCodeBuilder.reflectionHashCode(this, Collections.<String> emptyList());
    }
    
    public String toString() {
        return getSymbolicName() + "_" + getVersion();
    }
    
    @Override
    public boolean equals(Object obj) {
        return hashCode() == obj.hashCode();
    }
    
    /**
     * 没有被实现,会抛出{@link UnsupportedOerationException}
     * @deprecated
     */
    @Override
    public BundleDescription getSupplier() {
        throw new UnsupportedOperationException();
    }
    
    /**
     * 没有被实现,会抛出{@link UnsupportedOerationException}
     * @deprecated
     */
    @Override
    public String getLocation() {
        throw new UnsupportedOperationException();
    }

    /**
     * 没有被实现,会抛出{@link UnsupportedOerationException}
     * @deprecated
     */
    @Override
    public ExportPackageDescription[] getExportPackages() {
        throw new UnsupportedOperationException();
    }
    
    /**
     * 没有被实现,会抛出{@link UnsupportedOerationException}
     * @deprecated
     */
    @Override
    public ImportPackageSpecification[] getImportPackages() {
        throw new UnsupportedOperationException();
    }

    /**
     * 没有被实现,会抛出{@link UnsupportedOerationException}
     * @deprecated
     */
    @Override
    public GenericSpecification[] getGenericRequires() {
        throw new UnsupportedOperationException();
    }

    /**
     * 没有被实现,会抛出{@link UnsupportedOerationException}
     * @deprecated
     */
    @Override
    public GenericDescription[] getGenericCapabilities() {
        throw new UnsupportedOperationException();
    }

    /**
     * 没有被实现,会抛出{@link UnsupportedOerationException}
     * @deprecated
     */
    @Override
    public boolean hasDynamicImports() {
        throw new UnsupportedOperationException();
    }

    /**
     * 没有被实现,会抛出{@link UnsupportedOerationException}
     * @deprecated
     */
    @Override
    public ExportPackageDescription[] getSelectedExports() {
        throw new UnsupportedOperationException();
    }

    /**
     * 没有被实现,会抛出{@link UnsupportedOerationException}
     * @deprecated
     */
    @Override
    public BundleDescription[] getResolvedRequires() {
        throw new UnsupportedOperationException();
    }

    /**
     * 没有被实现,会抛出{@link UnsupportedOerationException}
     * @deprecated
     */
    @Override
    public ExportPackageDescription[] getResolvedImports() {
        throw new UnsupportedOperationException();
    }

    /**
     * 没有被实现,会抛出{@link UnsupportedOerationException}
     * @deprecated
     */
    @Override
    public boolean isResolved() {
        throw new UnsupportedOperationException();
    }

    /**
     * 没有被实现,会抛出{@link UnsupportedOerationException}
     * @deprecated
     */
    @Override
    public State getContainingState() {
        throw new UnsupportedOperationException();
    }

    /**
     * 没有被实现,会抛出{@link UnsupportedOerationException}
     * @deprecated
     */
    @Override
    public HostSpecification getHost() {
        throw new UnsupportedOperationException();
    }

    /**
     * 没有被实现,会抛出{@link UnsupportedOerationException}
     * @deprecated
     */
    @Override
    public long getBundleId() {
        throw new UnsupportedOperationException();
    }

    /**
     * 没有被实现,会抛出{@link UnsupportedOerationException}
     * @deprecated
     */
    @Override
    public BundleDescription[] getFragments() {
        throw new UnsupportedOperationException();
    }

    /**
     * 没有被实现,会抛出{@link UnsupportedOerationException}
     * @deprecated
     */
    @Override
    public boolean isSingleton() {
        throw new UnsupportedOperationException();
    }

    /**
     * 没有被实现,会抛出{@link UnsupportedOerationException}
     * @deprecated
     */
    @Override
    public boolean isRemovalPending() {
        throw new UnsupportedOperationException();
    }

    /**
     * 没有被实现,会抛出{@link UnsupportedOerationException}
     * @deprecated
     */
    @Override
    public BundleDescription[] getDependents() {
        throw new UnsupportedOperationException();
    }

    /**
     * 没有被实现,会抛出{@link UnsupportedOerationException}
     * @deprecated
     */
    @Override
    public Object getUserObject() {
        throw new UnsupportedOperationException();
    }

    /**
     * 没有被实现,会抛出{@link UnsupportedOerationException}
     * @deprecated
     */
    @Override
    public void setUserObject(Object userObject) {
        throw new UnsupportedOperationException();        
    }

    /**
     * 没有被实现,会抛出{@link UnsupportedOerationException}
     * @deprecated
     */
    @Override
    public boolean attachFragments() {
        throw new UnsupportedOperationException();
    }

    /**
     * 没有被实现,会抛出{@link UnsupportedOerationException}
     * @deprecated
     */
    @Override
    public boolean dynamicFragments() {
        throw new UnsupportedOperationException();
    }

    /**
     * 没有被实现,会抛出{@link UnsupportedOerationException}
     * @deprecated
     */
    @Override
    public NativeCodeSpecification getNativeCodeSpecification() {
        throw new UnsupportedOperationException();
    }

    /**
     * 没有被实现,会抛出{@link UnsupportedOerationException}
     * @deprecated
     */
    @Override
    public ExportPackageDescription[] getSubstitutedExports() {
        throw new UnsupportedOperationException();
    }
    
    /**
     * 没有被实现,会抛出{@link UnsupportedOerationException}
     * @deprecated
     */
    @Override
    public String getPlatformFilter() {
        throw new UnsupportedOperationException();
    }

}
